<template>
  <div class="editor">
    <quill-editor
      ref="editorRef"
      v-model:content="content"
      :options="options"
      contentType="html"
      @ready="onEditorReady"
    ></quill-editor>
  </div>
</template>

<script setup lang="ts">
// 引入富文本编辑器、类型定义与样式
import { QuillEditor, Quill } from '@vueup/vue-quill'

import '@vueup/vue-quill/dist/vue-quill.snow.css'

// 引入图片缩放插件 (注意：这里我们不再需要全局注册)
import BlotFormatter from 'quill-blot-formatter'

// 使用 shallowRef 来存储编辑器实例，避免不必要的深度响应式处理
const editorRef = shallowRef<any>()
const content = ref('')

// --- 自定义处理器 ---

// 1. 图片上传处理器 (Base64 方案)
const imageHandler = () => {
  if (!editorRef.value) return

  const input = document.createElement('input')
  input.setAttribute('type', 'file')
  input.setAttribute('accept', 'image/*')
  input.click()

  input.onchange = () => {
    const file = input.files?.[0]
    if (file) {
      const reader = new FileReader()
      reader.onload = (e) => {
        const base64 = e.target?.result
        if (base64) {
          const quill = editorRef.value!.getQuill()
          const range = quill.getSelection(true)
          // 在光标处插入图片
          quill.insertEmbed(range.index, 'image', base64 as string)
          // 插入后光标移到图片后面
          quill.setSelection(range.index + 1, 0)
        } else {
          alert('图片读取失败')
        }
      }
      reader.onerror = () => {
        alert('图片读取失败')
      }
      reader.readAsDataURL(file)

      /*
       * --- 如果有后端接口，应该这样写 ---
       * const formData = new FormData();
       * formData.append('file', file);
       * try {
       *   // 伪代码：调用你的上传API
       *   // const res = await yourUploadApi(formData);
       *   // const imageUrl = res.data.url; // 假设后端返回图片URL
       *
       *   // 获取编辑器实例和光标位置
       *   const quill = editorRef.value.getQuill();
       *   const range = quill.getSelection(true);
       *   // 插入服务器返回的图片URL
       *   quill.insertEmbed(range.index, 'image', imageUrl);
       *   quill.setSelection(range.index + 1, 0);
       * } catch (error) {
       *   console.error('上传失败:', error);
       *   alert('图片上传失败');
       * }
       */
    }
  }
}

// 2. 视频 "上传" 处理器 (createObjectURL 方案，仅用于演示)
const videoHandler = () => {
  if (!editorRef.value) return

  const input = document.createElement('input');
  input.setAttribute('type', 'file');
  input.setAttribute('accept', 'video/*');
  input.click();

  input.onchange = () => {
    const file = input.files?.[0];
    if (file) {
      // 警告：此 URL 仅在当前会话中有效，刷新后失效！
      const videoUrl = URL.createObjectURL(file);
      const quill = editorRef.value!.getQuill();
      const range = quill.getSelection(true);
      quill.insertEmbed(range.index, 'video', videoUrl);
      quill.setSelection(range.index + 1, 0);
    }
  };
}


// --- 富文本配置 ---
const options: any = {
  theme: 'snow',
  placeholder: '请输入内容...',
  modules: {
    // 1. 移除全局注册，直接将模块类传入
    blotFormatter: {}, // BlotFormatter 默认配置即可
    toolbar: {
      container: [
        ['bold', 'italic', 'underline', 'strike'],
        [{ color: [] }, { background: [] }],
        [{ align: [] }],
        [{ size: ['small', false, 'large', 'huge'] }],
        [{ font: [] }],
        [{ header: [1, 2, 3, 4, 5, 6, false] }],
        [{ list: 'ordered' }, { list: 'bullet' }],
        [{ indent: '-1' }, { indent: '+1' }],
        ['blockquote', 'code-block'],
        ['clean'],
        ['link', 'image', 'video'],
      ],
      // 2. 绑定自定义处理器
      handlers: {
        image: imageHandler,
        // video: videoHandler // 如果需要覆盖默认的视频URL输入，则取消此行注释
      },
    },
  },
}

// 注册 BlotFormatter 模块
Quill.register('modules/blotFormatter', BlotFormatter)


// --- 生命周期与辅助函数 ---

// 编辑器准备好后，添加自定义事件监听
const onEditorReady = () => {
  if (editorRef.value) {
    const quill = editorRef.value.getQuill()
    // 监听粘贴事件 (修复了事件名 'customPaste' -> 'paste')
    quill.root.addEventListener('paste', handlePaste, false)
  }
}

// 自定义粘贴处理
const handlePaste = (e: ClipboardEvent) => {
  if (e.clipboardData && e.clipboardData.files.length > 0) {
    e.preventDefault() // 阻止默认的粘贴行为
    const file = e.clipboardData.files[0]
    if (file.type.startsWith('image/')) {
      // 如果粘贴的是图片，则走我们的图片上传逻辑
      const reader = new FileReader()
      reader.onload = (evt) => {
        const base64 = evt.target?.result
        if (base64 && editorRef.value) {
          const quill = editorRef.value.getQuill()
          const range = quill.getSelection(true)
          quill.insertEmbed(range.index, 'image', base64 as string)
          quill.setSelection(range.index + 1, 0)
        }
      }
      reader.readAsDataURL(file)
    } else {
      // 其他文件类型可以提示用户不支持
      alert('不支持粘贴此类型文件！')
    }
  }
}

// 给工具栏按钮添加 title 提示
const initTitle = () => {
  const titleConfig = [
    { Choice: '.ql-bold', title: '加粗' },
    { Choice: '.ql-italic', title: '斜体' },
    { Choice: '.ql-underline', title: '下划线' },
    { Choice: '.ql-strike', title: '删除线' },
    { Choice: '.ql-blockquote', title: '块引用' },
    { Choice: '.ql-code-block', title: '代码块' },
    { Choice: '.ql-header[value="1"]', title: '标题一' },
    { Choice: '.ql-header[value="2"]', title: '标题二' },
    { Choice: '.ql-list[value="ordered"]', title: '有序列表' },
    { Choice: '.ql-list[value="bullet"]', title: '无序列表' },
    { Choice: '.ql-indent[value="-1"]', title: '向左缩进' },
    { Choice: '.ql-indent[value="+1"]', title: '向右缩进' },
    { Choice: '.ql-align', title: '对齐方式' },
    { Choice: '.ql-clean', title: '清除格式' },
    { Choice: '.ql-link', title: '链接' },
    { Choice: '.ql-image', title: '图片' },
    { Choice: '.ql-video', title: '视频' },
  ]
  for (const item of titleConfig) {
    const tip = document.querySelector(`.editor ${item.Choice}`)
    if (tip) {
      tip.setAttribute('title', item.title)
    }
  }
}

onMounted(() => {
  nextTick(() => {
    initTitle()
  })
})

onUnmounted(() => {
  if (editorRef.value) {
    const quill = editorRef.value.getQuill();
    quill.root.removeEventListener('paste', handlePaste, false);
  }
});

</script>

<style scoped lang="scss">
.editor {
  width: 100%;
  :deep(.ql-editor) {
    min-height: 300px; /* 增加最小高度以便测试 */
  }
  :deep(.ql-toolbar.ql-snow) {
    border-color: #dcdfe6;
    border-radius: 4px 4px 0 0;
  }
  :deep(.ql-container.ql-snow) {
    border-color: #dcdfe6;
    border-radius: 0 0 4px 4px;
  }
}
</style>
